package iterator

import "errors"

type tLinkedList struct {
	size int
	head *tLinkedNode
	tail *tLinkedNode
}

func NewLinkedList() ILinkedList {
	return &tLinkedList{
		0, nil, nil,
	}
}

type tLinkedNode struct {
	value interface{}
	next *tLinkedNode
}

func newLinkedNode(v interface{}) *tLinkedNode {
	return &tLinkedNode{
		v, nil,
	}
}

func (me *tLinkedList) Size() int {
	return me.size
}

func (me *tLinkedList) Push(it interface{}) {
	node := newLinkedNode(it)
	if me.head == nil {
		me.head, me.tail = node, node

	} else {
		me.tail.next = node
		me.tail = node
	}
	me.size++
}

func (me *tLinkedList) Poll() (error,  interface{}) {
	if me.size <= 0 {
		return errors.New("empty list"), nil
	}

	node := me.head
	me.head = me.head.next
	me.size--
	return nil, node.value
}

func (me *tLinkedList) Iterator() IIterator {
	return newLinkedListIterator(me)
}